package pf.springBoot.springBootSSO.controller;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

//import pf.java.pfHelper.CookieUtils;
import pf.java.pfHelperNotSpring.FuncAuthorityClass;
import pf.java.pfHelper.PFCaching;
//import pf.java.pfHelper.SpringHttpUtil;
import pf.java.pfHelperNotSpring.TreeListItem;
import pf.java.pfHelper.config.PFAppConfig;
//import pf.java.pfHelper.config.PFCookieUtils;
import pf.java.pfHelper.config.PFDataHelper;
import pf.java.pfHelper.model.SystemUser;
import pf.java.pfHelperMvc.config.PFCookieUtils;
import pf.springBoot.springBootSSO.controller.shares.YJQueryController;
import pf.springBoot.springBootSSO.model.SystemMonth;
import pf.springBoot.springBootSSO.model.WebMenu;
import pf.springBoot.springBootSSO.oAuth.FormsAuth;
import pf.springBoot.springBootSSO.oAuth.LoginerBase;
import pf.springBoot.springBootSSO.oAuth.TestBean;
import pf.springBoot.springBootSSO.service.UserService;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.DOMReader;
import org.dom4j.io.SAXReader;

@RestController
public class HomeController extends  YJQueryController {
    private  UserService _service;
//    private  BalanceService _balanceService;
    private String cookieKey="cookieKey";
//    @Autowired
//    private SpringHttpUtil springHttpUtil;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private PFCookieUtils cookieUtils;
    @Autowired
    private static PFAppConfig _appConfig;
// @Autowired
//  private PFCookieUtils2 cookieUtils2;
    @Autowired
	public HomeController(PFAppConfig appConfig) {
		_service=new UserService();
		_appConfig=appConfig;
	}
//	   @GetMapping("/GetUserExData")
//	    public LoginerBase GetUserExData()  {  
//		   return FormsAuth.GetUserDataT(LoginerBase.class);
//	       //return FormsAuth.GetUserExData(SystemUser.class);     
//	    }
	   @GetMapping("/GetReadFromLocal")
	    public String GetReadFromLocal()  {  
		   return PFDataHelper.ReadLocalJson("LoginCheck.json");
	    }
	   @GetMapping("/GetReadFromClassSource")
	    public String GetReadFromClassSource()  {  
		   return PFDataHelper.ReadLocalJsonFromClassSource("LoginCheck.json");
	    }
	   @GetMapping("/GetWriteError")
	    public Boolean GetWriteError()  {  
	    	PFDataHelper.WriteLog("aaaaaaaaaaa");
		   return true;  
	    }
	   @GetMapping("/GetUserExData")
	    public SystemUser GetUserExData()  {  
	    	SystemUser userData = FormsAuth.GetUserExData(SystemUser.class);
		   return userData;  
	    }
	   @GetMapping("/UseLocalData")
	    public Boolean UseLocalData()  {  
		   //return _appConfig.getUseLocalData(); //ok
		   return TestBean.UseLocalData();
//	       return PFDataHelper.UseLocalData();     
	    }
	   @GetMapping("/GetCookie")
	    public String GetCookie()  { 
		   //Cookie a=PFCookieUtils2.getCookie(cookieKey);
		   //Cookie a=PFCookieUtils.getCookie(cookieKey);
//		   Cookie a=cookieUtils.getCookie(cookieKey);
	       return PFCookieUtils.getCookieValue(cookieKey);	  
	       //return cookieUtils.getCookieValue(cookieKey);     
	    }
	   @GetMapping("/SetCookie")
	    public Boolean SetCookie(String value)  {   	
//	       Map<String, String> map = new HashMap<>();
//	    	map.put("aaaaa","aaa");
//	    	map.put("bbbbb","bbb");
//	    	springHttpUtil.setCookie(map);  
	    	
	       //CookieUtils.setCookie(cookieKey,"aabb");	  
		   PFCookieUtils.setCookie(cookieKey, value);
	       //cookieUtils.setCookie(cookieKey, value);
	       return true;
	    }
	   @GetMapping("/GetCache")
	    public Object GetCache()  { 
		   //Cookie a=PFCookieUtils2.getCookie(cookieKey);
		   //Cookie a=PFCookieUtils.getCookie(cookieKey);
//		   Cookie a=cookieUtils.getCookie(cookieKey);
	       return PFCaching.Get(cookieKey);	  
	       //return cookieUtils.getCookieValue(cookieKey);     
	    }
	   @GetMapping("/SetCache")
	    public Boolean SetCache(String value)  {   	
//	       Map<String, String> map = new HashMap<>();
//	    	map.put("aaaaa","aaa");
//	    	map.put("bbbbb","bbb");
//	    	springHttpUtil.setCookie(map);  
	    	
	       //CookieUtils.setCookie(cookieKey,"aabb");	  
		   PFCaching.Set(cookieKey, value);
	       //cookieUtils.setCookie(cookieKey, value);
	       return true;
	    }
		//测试方法--benjamin todo
	   @GetMapping("/testreplaceindex")
	    public ModelAndView TestReplaceIndex()  {	   
	       ModelAndView mv=new ModelAndView("Home/TestReplaceIndex");	       
	       return mv;	       
	    }
	   @GetMapping("/testlayoutindex")
	    public ModelAndView TestLayoutIndex()  {	   
	       ModelAndView mv=new ModelAndView("Home/TestLayoutIndex");	       
	       return mv;	       
	    }
   @GetMapping("/")
    public ModelAndView Index() throws DocumentException, IOException {	   
       //ModelAndView mv=new ModelAndView("Home/Index");
       
       Boolean showMonthDialog = PFDataHelper.StringIsNullOrWhiteSpace(GetCurrentYm());
       if (showMonthDialog)
       {
    	   List<SystemMonth> months = _service.GetSystemMonths();
    	   ViewData.put("monList", PFDataHelper.ListToMap(months, 
    			   (a) -> {return a.DatabaseName;}, 
    			   (a)-> {return a.DatabaseName;}));
           //if (SystemUser != null) {
    	   SystemUser user=GetSystemUser();
    	   if(user==null) {user=new SystemUser();}
           user.MaxMonth = months.stream().map(a->a.getCmonth()).max((a, b) -> {
               if (a.compareTo(b) > 0) {
                   return 1;
               } else {return -1;}
           }).get();
           SetSystemUser(user);
           //}
       }
       ViewData.put("showMonthDialog", showMonthDialog);

       //用户切换分公司好还是切换省份好
       //var orgList = new List<KeyValuePair<object, object>>();
       if (GetSystemUser() != null && GetSystemUser().OrgList!=null)
       {
    	   ViewData.put("orgList", PFDataHelper.ListToMap(GetSystemUser().OrgList, 
    			   (a) -> {return a.Org;}, 
    			   (a)-> {return a.OrgName;}));           
       }
       
       Object[] modules=GetMoudleAndMenu().keySet().toArray();
       ViewData.put("modules",modules );    
       
       //ViewData["modules"] = GetMoudleAndMenu().Keys.ToArray();

       ViewData.put("userName", FormsAuth.GetUserData().UserName);
      //return mv;
       return View("Home/Index");
    }
   /// <summary>
   /// 是否显示该模块
   /// </summary>
   /// <param name="menus"></param>
   /// <returns></returns>
   private static Boolean IsShowModule(List<TreeListItem> menus)
   {
       //return menus != null && menus.Any(a=>(!string.IsNullOrWhiteSpace(((WebMenu)a.Data).Url))||(a.Children!=null&&a.Children.Any()));
       return menus.size()>0;//之前已经用FilterByLeaf过滤了
   }
   @GetMapping("/Home/ModuleMenu")
   public ModelAndView ModuleMenu(String moduleName)
   {
	   List<TreeListItem> model = GetMoudleMenu(moduleName);
       return View(model,"Home/ModuleMenu");
   }
   public static Document GetSysMenuDocument() {
       Resource resource = new ClassPathResource("XmlConfig/SysMenu.xml");
       SAXReader saxReader = new SAXReader();
//       Document doc = saxReader.read(resource.getFile());
       try {
		return saxReader.read(resource.getInputStream());
	} catch (DocumentException | IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}     
       return null;
   }
   private List<TreeListItem> GetMoudleMenu(String moudleName)
   {
//       Resource resource = new ClassPathResource("SysMenu.xml");
//       SAXReader saxReader = new SAXReader();
       Document doc=GetSysMenuDocument();
//       try {
//		doc = saxReader.read(resource.getFile());
//	} catch (DocumentException | IOException e) {
//		PFDataHelper.WriteError(e);
//		return null;
//	}   
       
//       String xmlfile = Paths.get(HttpRuntime.AppDomainAppPath, "Configs/XmlConfig/SysMenu.xml");
//       XmlDocument doc = new XmlDocument();
       //doc.Load(xmlfile);
       
       List<TreeListItem> menus = new ArrayList<TreeListItem>();
       
       //return null;
       
       List nodes = doc.getRootElement().selectNodes(PFDataHelper.FormatString("/Menus/Menu[@name='{0}']/Menus/Menu", moudleName));
       if (nodes != null && nodes.size() > 0)
       {
           SetMenu( menus, nodes);
       }
       return menus;
   }
   public static Map<String, List<TreeListItem>> GetMoudleAndMenu() throws DocumentException, IOException
   {
//       Resource resource = new ClassPathResource("XmlConfig/SysMenu.xml");
//       SAXReader saxReader = new SAXReader();
////       Document doc = saxReader.read(resource.getFile());
//       Document doc = saxReader.read(resource.getInputStream());  
       Document doc=GetSysMenuDocument();     
       
//       
//       string xmlfile = Path.Combine(HttpRuntime.AppDomainAppPath, "Configs/XmlConfig/SysMenu.xml");
//       XmlDocument doc = new XmlDocument();
//       doc.Load(xmlfile);

       List<Element> modules = doc.getRootElement().elements();//第一层Menu即为Module
       Map<String, List<TreeListItem>> result = new LinkedHashMap<String,List<TreeListItem>>();
       

       for (Element module : modules) {
    	   List<TreeListItem> menus = new ArrayList<TreeListItem>();
//    	   List<Element> nodes = module.elements("Menus/Menu");
    	   List<Element> nodes = module.element("Menus").elements("Menu");
           if (nodes != null && nodes.size() > 0)
           {
               SetMenu( menus, nodes);
           }
           if (IsShowModule(menus))
           {
               result.put(module.attribute("name").getValue(), menus);
           }
       }
       return result;
   }
   private static void SetMenu( List<TreeListItem> list, List<Element> nodes)
   {
       DoSetMenu( list, nodes);
       //过滤末级不是功能的部分(因为没权限)--benjamin20190709
       TreeListItem treeListItem=new TreeListItem();
       treeListItem.SetChildren(list);
       treeListItem.FilterByLeaf(a -> !PFDataHelper.StringIsNullOrWhiteSpace(((WebMenu)a.GetData()).Url));
       list =treeListItem.GetChildren();
   }
   private static void DoSetMenu( List<TreeListItem> list, List<Element> nodes)
   {
       //list = new List<TreeListItem>();
	   Map<String, FuncAuthorityClass> funcAuthorities = FormsAuth.GetFuncAuthorities();
       try
       {
           for (Element node : nodes)
           {        	   
        	   
//               if ((!PFDataHelper.IsCompilationDebug)
//                   && node.Attributes["debug"] != null&& node.Attributes["debug"].Value=="true"
//                   )
//               {
//                   continue;
//               }
        	   
        	   TreeListItem item = new TreeListItem();
               item.SetData(new WebMenu());
               ((WebMenu)item.GetData()).Menuname = node.attribute("name").getValue();
               if (node.attribute("url") != null)
               {
            	   //benjamin todo
//                   //组成权限系统的功能码,格式如:	YJQ_Hyzl_YWYZL_FirstStep
//                   String authorizeCode = String.format("YJQ%s", node.attribute("url").getValue().split("?")[0].replace("/", "_"));
//                   
//                   if ((!funcAuthorities.containsKey(authorizeCode))
//                       &&(node.attribute("allUser") == null || node.attribute("allUser").getValue() != "true")
//                       )
//                   {
//                       continue;
//                   }
                   ((WebMenu)item.GetData()).Url = node.attribute("url").getValue();
               }
               if (node.attribute("icon") != null)
               {
                   ((WebMenu)item.GetData()).Icon = node.attribute("icon").getValue();
               }
               @SuppressWarnings("unchecked")
//               List<Element> children = node.elements("Menus/Menu");
               Element childrenP=node.element("Menus");
               if(childrenP!=null) {
                   List<Element> children = childrenP.elements("Menu");
                   if (children != null && children.size() > 0)
                   {
                	   List<TreeListItem> cList = new ArrayList<TreeListItem>();
                       DoSetMenu( cList, children);//注意,虽然children不为空,但并不能保证list也不为空,因为可能被权限过滤了
                       if (cList.size() > 0) { item.SetChildren(cList); }
                   }
               }
               list.add(item);
           }
           //list=new TreeListItem { Children= list }.FilterByLeaf(a => !PFDataHelper.StringIsNullOrWhiteSpace(((WebMenu)a.Data).Url)).Children;
       }
       catch(Exception e)
       {
    	   Exception aa = e;
       }
   }
}